package net.wanglu.www.zzz.rule.sva;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Pattern;

import net.wanglu.www.zzz.rule.BadEgg;
import net.wanglu.www.zzz.rule.Rule;
import net.wanglu.www.zzz.service.se.nsubj._NSubjTuple;

import edu.stanford.nlp.ling.TaggedWord;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.trees.TreeGraphNode;

public class NounPrepAsSubj extends _SvaRule {

	public static final Pattern NounPrep = Pattern
			.compile("\\bwith\\b|\\balong with\\b|\\btogether\\b|\\bin company with\\b|\\baccompanied by\\b|\\blike\\b|\\bbut\\b|\\bexcept\\b|\\bas well as\\b|\\bno less than\\b|\\brather than\\b|\\bmore than\\b|\\bas much as\\b|\\bincluding\\b|\\bin addition to\\b|\\bbesides\\b");

	@Override
	public Object applicable(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		if ( super.applicable(objects) == Rule.Inapplicable) return Rule.Inapplicable;
		_NSubjTuple nst = (_NSubjTuple) objects[1];
		if ( !"NP".equals(nst.getSubjectAncestor().value())) return Rule.Inapplicable;
		return Rule.Applicable;
	}

	@Override
	public Object deviseRightSolution(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		return super.deviseRightSolution(objects);
	}

	@Override
	public Object examine(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		HashMap<?, ?> preprocessData = (HashMap<?, ?>) objects[0];
		_NSubjTuple nst =  (_NSubjTuple) objects[1];
		
		if ( this.applicable(preprocessData, nst) == Rule.Inapplicable) return Rule.Inapplicable;
		TreeGraphNode subj = (TreeGraphNode) nst.getSubj();
		TreeGraphNode verb = (TreeGraphNode) nst.getVerb();
		TreeGraphNode cop = (TreeGraphNode) nst.getCop();
		TreeGraphNode closestAux = (TreeGraphNode) nst.getAux();
		Tree subjAncestor = nst.getSubjectAncestor();
		
		TreeGraphNode pred = verb;
		if ( cop != null) pred = cop;
		if ( closestAux != null) pred = closestAux;
		String predWord = pred.label().word();
		String predTag = pred.label().tag();

		ArrayList<TaggedWord> tags = subjAncestor.taggedYield();
		sb.clear();
		for (int j = 0; j < tags.size(); j++) {
			sb.append(tags.get(j).word()).append(" ");
		}

		if (NounPrep.matcher(sb.toString()).find()) {
			String subjTag = subj.label().tag();
			if ("NNS".equals(subjTag) || "NNPS".equals(subjTag)) {
				if (Rule.PluralVerb.matcher(predTag).find() && !"was".equals(predWord)) {
					return null;
				} else {
					BadEgg egg = new BadEgg();
					egg.setProperty(BadEgg.Error);
					egg.setViolatedRule(this);
					egg.whereIsWrong = nst;
					return egg;
				}
			} else if ("NN".equals(subjTag) || "NNP".equals(subjTag)) {
				if (Rule.SingularVerb.matcher(predTag).find() && !"were".equals(predWord)) {
					return null;
				} else {
					BadEgg egg = new BadEgg();
					egg.setProperty(BadEgg.Error);
					egg.setViolatedRule(this);
					egg.whereIsWrong = nst;
					return egg;
				}
			}
		}
		return Rule.Inapplicable;
	}

	@Override
	public Object whyItsWrong(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		sb.clear();
		sb.append("<p>");
		sb
				.append("如果主语后面跟有with，along with，together，in company with，accompanied by，like，but，except，as well as，no less than，rather than，more than，as much as，including，in addition to，besides等引起的短语，谓语动词的数与作主语的中心词保持一致，如果主语是单数，谓语动词就用单数形式；如果主语是复数，谓语动词就用复数形式。例如：");
		sb.append("<br>");
		sb.append("The teacher with two students was at the meeting.");
		sb.append("<br>");
		sb.append("The girl as well as the boys has learned to drive a car.");
		sb.append("<br>");
		sb
				.append("A library with five thousand books is offered to the nation as a gift.");
		sb.append("<br>");
		sb
				.append("E-mail, as well as telephones, is playing an important part in daily communication.");
		sb.append("<br>");
		sb.append("Nobody but Jane knows the secret.");
		sb.append("<br>");
		sb.append("All but one were here just now.");
		sb.append("<br>");
		sb.append("注意：在口语或非正式文体中，也可根据意义一致的原则或就近原则，采用复数形式的谓语动词。例如：");
		sb.append("<br>");
		sb.append("A woman with two children, all shivering with cold, were asking to stay in the house.");
		sb.append("</p>");
		return sb.toString();
	}
}
